package com.xiaoxin.experience.util;

import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;

/**
 * @author xiaoxin
 */
public class ResizeImgBase64Util
{

    private static final Logger log = LoggerFactory.getLogger(ResizeImgBase64Util.class);

    private ResizeImgBase64Util(){}

    private static final long KIL_BYTES = 1024;

    public static String resizeImageStreamByLimit(InputStream in, Long limitSize)
    {
        return resizeImageStreamByLimit(in,limitSize,"jpg");
    }

    public static String resizeImageStreamByLimit(InputStream in, Long limitSize,String format)
    {
        return resizeImageByLimit(Base64ChangeUtil.readInputStreamToBase64(in),limitSize,format);
    }

    /**
     * 调整图片大小到指定大小
     * @param imgBase64 图片base64编码
     * @param limitSize 限制大小 (单位:kb)
     * @return 符合限定大小
     */
    public static String resizeImageByLimit(String imgBase64, Long limitSize, String format)
    {
        Assert.hasText(imgBase64,"img base64 can not be null");
        Assert.isTrue(limitSize > 0, "limit size is valid");
        limitSize = limitSize * KIL_BYTES;
        long imageSize = imageSize(imgBase64);
        while (imageSize > limitSize)
        {
            imgBase64 = resizeImage(imgBase64,format);
            imageSize = imageSize(imgBase64);
        }
        return imgBase64;
    }

    public static String resizeImage(InputStream in, int width,int length,String format) throws IOException {
        String imgBase64 = Base64ChangeUtil.readInputStreamToBase64(in);
        BufferedImage src = base64String2BufferedImage(imgBase64);
        BufferedImage output = Thumbnails.of(src).size(src.getWidth(), src.getHeight()).asBufferedImage();
        output = Thumbnails.of(output).forceSize(width,length).asBufferedImage();
        return imageToBase64(output,format);
    }

    /**
     * 重置图片大小
     * @param base64Img 图片base64编码
     * @return 图片压缩后的base64编码
     */
    public static String resizeImage(String base64Img,String format)
    {
        try
        {
            BufferedImage src = base64String2BufferedImage(base64Img);
            BufferedImage output = Thumbnails.of(src).size(src.getWidth(), src.getHeight()).asBufferedImage();
            output = Thumbnails.of(output).scale(0.8).asBufferedImage();
            return imageToBase64(output,format);
        }
        catch (Exception e)
        {
            log.error("resize image fail: ",e);
        }
        return base64Img;
    }

    public static BufferedImage base64String2BufferedImage(String base64string)
    {
        try
        {
            InputStream stream = base64ToInputStream(base64string);
            return ImageIO.read(stream);
        } catch (Exception e)
        {
            log.error("base64 to picture fail: ",e);
        }
        return new BufferedImage(0,0,0);
    }

    private static InputStream base64ToInputStream(String base64string)
    {
        try
        {
            byte[] bytes = Base64.getDecoder().decode(base64string);
            return new ByteArrayInputStream(bytes);
        }
        catch (Exception e)
        {
            log.error("base64 string loading fail: ",e);
        }
        return new ByteArrayInputStream(new byte[0]);
    }

    /**
     * bufferedImage对象转成base64字符串
     * @param bufferedImage 图片对象
     * @return base64字符串
     */
    public static String imageToBase64(BufferedImage bufferedImage,String format)
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Base64.Encoder encoder = Base64.getEncoder();
        try
        {
            ImageIO.write(bufferedImage, format, baos);
            return new String(encoder.encode((baos.toByteArray())));
        }
        catch (IOException e)
        {
            log.error("Picture conversion fail",e);
        }
        return "";
    }

    public static String imageToBase64(BufferedImage bufferedImage)
    {
        return imageToBase64(bufferedImage,"jpg");
    }

    /**
     *通过图片base64流判断图片等于多少字节
     *image 图片流
     */
    public static int imageSize(String image)
    {
        // 1.需要计算文件流大小，首先把头部的data:image/png;base64,（注意有逗号）去掉。
        String str = image.substring(22);

        //2.找到等号，把等号也去掉
        int equalIndex = str.indexOf("=");
        if(equalIndex > 0)
        {
            str=str.substring(0, equalIndex);
        }
        //3.原来的字符流大小，单位为字节
        int strLength = str.length();
        return strLength - (strLength/8) * 2;
    }
}
